package com.meiji.toutiao.util;

import android.support.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;

/**
 * https://juejin.im/entry/58ff2e26a0bb9f0065d2c5f2
 * <p>
 * 功能：rxBus 工具类
 */


public class RxBus {

	// 线程安全
	private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<>();

	private RxBus() {

	}

	@NonNull
	public static RxBus getInstance() {          // 获取rxBus对象
		return Holder.instance;
	}

	@NonNull
	public <T> Observable<T> register(@NonNull Class<T> clz) {   // 参数是类的
		return register(clz.getName());                        // 默认的调用使用tag构造方法
	}

	@NonNull
	public <T> Observable<T> register(@NonNull Object tag) {  //参数是tag构造方法
		List<Subject> subjectList = subjectMapper.get(tag);
		if (null == subjectList) {
			subjectList = new ArrayList<>();
			subjectMapper.put(tag, subjectList);
		}

		Subject<T> subject = PublishSubject.create();
		subjectList.add(subject);

		//System.out.println("注册到rxbus");
		return subject;
	}

	public <T> void unregister(@NonNull Class<T> clz, @NonNull Observable observable) {
		unregister(clz.getName(), observable);
	}

	public void unregister(@NonNull Object tag, @NonNull Observable observable) {
		List<Subject> subjects = subjectMapper.get(tag);
		if (null != subjects) {
			subjects.remove(observable);
			if (subjects.isEmpty()) {
				subjectMapper.remove(tag);
				//System.out.println("从rxbus取消注册");
			}
		}
	}

	// 发送一个的，默认的调用发送两个的方法
	public void post(@NonNull Object content) {
		post(content.getClass().getName(), content);
	}

	// rxBus发送事件，发送一个tag标示的，内容为object的数据
	public void post(@NonNull Object tag, @NonNull Object content) {
		List<Subject> subjects = subjectMapper.get(tag);
		if (!subjects.isEmpty()) {
			for (Subject subject : subjects) {
				subject.onNext(content);
			}
		}
	}

	// 私有内部类 ，持有RxBus的对象
	private static class Holder {
		private static RxBus instance = new RxBus();
	}
}
